<?php
/**
 * Each engineer has a duty to keep the code elegant
 * Created by wolffy.
 * Author @wolffy<13750088090@sina.cn>
 * Date: 2018/8/10
 * Time: 16:43
 */
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Str;

function isMobile($string)
{
    return !!preg_match('/^1[3|4|5|7|8]\d{9}$/', trim($string));
}

/**
 * 身份证号码校验
 * @param $id_card
 * @return bool
 */
function validation_filter_id_card($id_card)
{

    if(strlen($id_card)==18){

        return idcard_checksum18($id_card);

    }elseif((strlen($id_card)==15)){

        $id_card=idcard_15to18($id_card);

        return idcard_checksum18($id_card);

    }else{

        return false;

    }

}

// 计算身份证校验码，根据国家标准GB 11643-1999

function idcard_verify_number($idcard_base)
{

    if(strlen($idcard_base)!=17){

        return false;

    }

    //加权因子

    $factor=array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2);

    //校验码对应值

    $verify_number_list=array('1','0','X','9','8','7','6','5','4','3','2');

    $checksum=0;

    for($i=0;$i<strlen($idcard_base);$i++){

        $checksum += substr($idcard_base,$i,1) * $factor[$i];

    }

    $mod=$checksum % 11;

    $verify_number=$verify_number_list[$mod];

    return $verify_number;

}

// 将15位身份证升级到18位

function idcard_15to18($idcard)
{

    if(strlen($idcard)!=15){

        return false;

    }else{

        // 如果身份证顺序码是996 997 998 999，这些是为百岁以上老人的特殊编码

        if(array_search(substr($idcard,12,3),array('996','997','998','999')) !== false){

            $idcard=substr($idcard,0,6).'18'.substr($idcard,6,9);

        }else{

            $idcard=substr($idcard,0,6).'19'.substr($idcard,6,9);

        }

    }

    $idcard=$idcard.idcard_verify_number($idcard);

    return $idcard;

}

// 18位身份证校验码有效性检查

function idcard_checksum18($idcard)
{

    if(strlen($idcard)!=18){

        return false;

    }

    $idcard_base=substr($idcard,0,17);

    if(idcard_verify_number($idcard_base)!=strtoupper(substr($idcard,17,1))){

        return false;

    }else{

        return true;

    }

}

/**
 * 校验银行卡号码是否正确
 * @param $cardNumber
 * @return bool
 */
function check_bankCard($cardNumber)
{
    $cardNumber = findNum($cardNumber);
    $arr_no = str_split($cardNumber);
    $last_n = $arr_no[count($arr_no)-1];
    krsort($arr_no);
    $i = 1;
    $total = 0;
    foreach ($arr_no as $n){
        if($i%2==0){
            $ix = $n*2;
            if($ix>=10){
                $nx = 1 + ($ix % 10);
                $total += $nx;
            }else{
                $total += $ix;
            }
        }else{
            $total += $n;
        }
        $i++;
    }
    $total -= $last_n;
    $total *= 9;
    if($last_n == ($total%10)){
        return true;
    } else {
        return false;
    }
}

/**
 * 获取access_token
 * @return string
 */
function getAccessTokenStr()
{
    $header = Request::header('Authorization');
    if (Str::startsWith($header, 'Bearer ')) {
        return Str::substr($header, 7);
    }
    return "";
}

/**
 * 随机产生六位数
 *
 * @param int $len
 * @param string $format
 * @return string
 */
function __randStr($len = 4, $format = 'number')
{
    switch ($format) {
        case 'all':
            $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-@#~';
            break;
        case 'char':
            $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-@#~';
            break;
        case 'number':
            $chars = '0123456789';
            break;
        default :
            $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-@#~';
            break;
    }
    mt_srand((double)microtime() * 1000000 * getmypid());
    $password = "";
    while (strlen($password) < $len)
        $password .= substr($chars, (mt_rand() % strlen($chars)), 1);
    return $password;
}

/**
 * 获取阿里云oss图片地址
 * @param $key 图片路径或文件名
 * @return string
 */
function getOssImageUrl($key)
{
    return 'https://image.longmaoguanjia.com/' . $key . '?x-oss-process=style/image_style';
}

/**
 * 获取指定日期段内每一天的日期
 * @param $startdate
 * @param $enddate
 * @return
 */
function getDateFromRange($startdate, $enddate)
{
    $stimestamp = strtotime($startdate);
    $etimestamp = strtotime($enddate);
    // 计算日期段内有多少天
    $days = ($etimestamp-$stimestamp)/86400+1;
    // 保存每天日期
    $date = array();
    for($i=0; $i<$days; $i++) {
//        $date[$i]['date'] = date('Y-m-d', $stimestamp+(86400*$i));
        $date[$i] = $stimestamp+(86400*$i);
    }
    return $date;
}

/**
 * 求两个日期之间相差的天数
 * (针对1970年1月1日之后，求之前可以采用泰勒公式)
 * @param string $startdate
 * @param string $date2
 * @return number
 */
function diffDate($startdate, $enddate)
{
    if ($startdate > $enddate) {
        $startTime = strtotime($startdate);
        $endTime = strtotime($enddate);
    } else {
        $startTime = strtotime($enddate);
        $endTime = strtotime($startdate);
    }
    $diff = $startTime - $endTime;
    $day = $diff / 86400;
    return intval($day);
}

/**
 * 返回账单日期 还款日期 相差天数
 * @param $billDay
 * @param $repaymentDay
 * @return array
 */
function billRepaymentDate($billDay, $repaymentDay)
{
    if (10 > $billDay) {
        $billDay = 0 . (int)$billDay;
    }
    if (10 > $repaymentDay) {
        $repaymentDay = 0 . (int)$repaymentDay;
    }
    $billDate = date('Ym') . $billDay;
    $billLastDate = date('Ymd', strtotime("-1 months", strtotime($billDate)));
    $billNextDate = date('Ymd', strtotime("+1 months", strtotime($billDate)));
    $repaymentDateNow = date('Ym') . $repaymentDay;
    if ($billDate > $repaymentDateNow) {
        $repaymentDate = date('Ymd', strtotime("+1 months", strtotime($repaymentDateNow)));
        $repaymentLastDate = $repaymentDateNow;
        $repaymentNextDate = date('Ymd', strtotime("+1 months", strtotime($repaymentDate)));
    } else {
        $repaymentDate = $repaymentDateNow;
        $repaymentLastDate = date('Ymd', strtotime("-1 months", strtotime($repaymentDateNow)));
        $repaymentNextDate = date('Ymd', strtotime("+1 months", strtotime($repaymentDateNow)));
    }
    return [
        'bill_last_date' => $billLastDate,//上个月账单日
        'repayment_last_date' => $repaymentLastDate,//上个还款日
        'bill_date' => $billDate,//本月账单日
        'repayment_date' => $repaymentDate,//还款日
        'bill_next_date' => $billNextDate,//下个月账单日
        'repayment_next_date' => $repaymentNextDate,//下个还款日
        'diff_days' => diffDate($billDate, $repaymentDate),
    ];
}

function getMonthBillDate($billDay, $repaymentDay)
{
    $date = billRepaymentDate($billDay, $repaymentDay);
    if ($billDay > $repaymentDay) {
        //跨月 本月账单日比当前日期大，说明还没出账，还是拿上个月的作为月账单
        if (date('Y-m-d') < date('Y-m-d', strtotime($date['bill_date']))) {
            $monthBillDate = date('Y-m', strtotime($date['bill_last_date']));
        } else {
            $monthBillDate = date('Y-m');
        }
    } else {
        //不跨月 不管出不出账，都拿本月的作为月账单日期
        $monthBillDate = date('Y-m');
    }

    return $monthBillDate;
}

/**
 * 账单的状态：0待出账 1待更新 2待还清 3已还清 4已逾期
 *               当前日期<本月账单日 0待出账
 * 本月账单金额=0
 *               当前日期>本月账单日 1待更新
 *
 *               当前日期<本月账单日          0待出账
 *               本月账单日<当前日期<还款日期  2待还清
 * 本月账单金额>0                                   3已还清
 *               还款日期<当前日期 4已逾期
 */
function billStatus($billDate, $repaymentDate, $repaymentMoney)
{
    //当前日期
    $date = date('Ymd');
    if (0 < $repaymentMoney) {
        if ($date < $billDate) {
            return 0;//待出账
        }
        if ($date <= $repaymentDate) {
            return 2;//待还清
        }
        if ($date > $repaymentDate) {
            return 4;//已逾期
        }
    } else {
        if ($date < $billDate) {
            return 0;//待出账
        } else {
            return 2;//待更新 1
        }
    }
}

/**
 * 生成订单号
 * A 820 99190 50386 95
 * 2018 8月 20日
 * @return string
 */
function makeOrderNo()
{
    $yCode = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N',
        'O','P','Q','R','S','T','U','V','W','X','Y','Z');
    $orderSn = $yCode[intval(date('Y')) - 2018] .
        strtoupper(dechex(date('m'))) .
        date('d') .
        substr(time(),-5) .
        substr(microtime(),2,5) .
        sprintf('%02d',rand(0,99));
    return $orderSn;
}

/**
 * 不四舍五入保留小数点两位
 * @param $value
 * @return float|int
 */
function roundNo($value)
{
    $number = explode('.', $value);
    $decimal = isset($number[1]) ? 0 . '.' . substr($number[1], 0, 2) : 0;
    return $number[0] + $decimal;
}

/**
 * 四入五入保留小数点两位
 * @param $value
 * @return float|int
 */
function ceilDecimal($value, $num)
{
    $number = pow(10, $num);
    return ceil($value * $number) / $number;
}

/**
 * 生成某个范围内的随机时间
 * @param <type> $begintime  起始时间 格式为 Y-m-d H:i:s
 * @param <type> $endtime    结束时间 格式为 Y-m-d H:i:s
 * @param <type> $now         是否是时间戳 格式为 Boolean
 */
function randomDate($begintime, $endtime="", $now = true)
{
    $begin = strtotime($begintime);
    $end = $endtime == "" ? mktime(0,0,0,date('m'),date('d'),date('Y')) : strtotime($endtime);
    $timestamp = rand($begin, $end);
    return $now ? date("Y-m-d H:i:s", $timestamp) : $timestamp;
}

/**
 * 根据user_id邀请码加密
 * @param $userId
 * @return string
 */
function invitedEnCode($userId)
{
    static $source_string = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';
    $num = $userId;
    $code = '';
    while ( $num > 0) {
        $mod = $num % 35;
        $num = ($num - $mod) / 35;
        $code = $source_string[$mod].$code;
    }
    if(empty($code[3]))
        $code = str_pad($code,4,'0',STR_PAD_LEFT);
    return $code;
}

/**
 * 根据邀请码解密user_id
 * @param $code
 * @return bool|int
 */
function invitedDeCode($code)
{
    static $source_string = 'E5FCDG3HQA4B1NOPIJ2RSTUV67MWX89KLYZ';
    if (strrpos($code, '0') !== false)
        $code = substr($code, strrpos($code, '0')+1);
    $len = strlen($code);
    $code = strrev($code);
    $num = 0;
    for ($i=0; $i < $len; $i++) {
        $num += strpos($source_string, $code[$i]) * pow(35, $i);
    }
    return $num;
}

function invitedStrtolowerOI($str)
{
    $arr = str_split($str, 1);
    $res = '';
    foreach ($arr as $key=>$value) {
        if ('O' == $value)
            $value = 'o';
        if ('I' == $value)
            $value = 'i';
        $res .= $value;
    }
    return $res;
}

/**
 * 去掉不要的字段
 * @param $data
 * @param $keyName
 * @return array
 */
function unsetColumn($data, $keyName = [])
{
    $res = [];
    foreach ($data as $key=>$value) {
        foreach ($keyName as $val) {
            unset($value[$val]);
        }
        $res[$key] = $value;
    }
    return $res;
}

/**
 * 去除空格
 * @param $name
 * @return mixed
 */
function removeSpaceString($name)
{
   return preg_replace('# #','', $name);
}

/**
 * 手机号码中间转*
 * @param $mobile
 * @return mixed
 */
function hiddenMobile($mobile)
{
    return substr_replace($mobile,'****',3,4);
}

/**
 * 名字中间转*
 * @param $name
 * @return string
 */
function hiddenRealName($name)
{
    $name = preg_replace('# #','',$name);
    $length = mb_strlen($name,'utf8');
    if ($length <= 0)  return  '';
    $first = mb_substr($name,0,1,'utf-8') . '*';
    $last = '';
    if($length >= 3) {
        $last = mb_substr($name, -1, 1,'utf-8');
    }
    return $first . $last;
}

/**
 * 判断手机客户端
 * @return int
 */
function whatClientFromMobile()
{
    if (strpos($_SERVER['HTTP_USER_AGENT'], 'iPhone') || strpos($_SERVER['HTTP_USER_AGENT'], 'iPad')) {
        return 1;//IOS
    } else if (strpos($_SERVER['HTTP_USER_AGENT'], 'Android')) {
        return 2;//Android
    } else {
        return 3;//other
    }
}

/**
 * 将字符串参数变为数组
 * @param $query
 * @return array array (size=10)
'm' => string 'content' (length=7)
'c' => string 'index' (length=5)
'a' => string 'lists' (length=5)
'catid' => string '6' (length=1)
'area' => string '0' (length=1)
'author' => string '0' (length=1)
'h' => string '0' (length=1)
'region' => string '0' (length=1)
's' => string '1' (length=1)
'page' => string '1' (length=1)
 */
function convertUrlQuery($query)
{
    $queryParts = explode('&', $query);
    $params = array();
    foreach ($queryParts as $param) {
        $item = explode('=', $param);
        $params[$item[0]] = $item[1];
    }
    return $params;
}

/**
 * 将参数变为字符串
 * @param $array_query
 * @return string string 'm=content&c=index&a=lists&catid=6&area=0&author=0&h=0&region=0&s=1&page=1' (length=73)
 */
function getUrlQuery($array_query)
{
    $tmp = array();
    foreach($array_query as $k=>$param)
    {
        $tmp[] = $k.'='.$param;
    }
    $params = implode('&',$tmp);
    return $params;
}

function findNum($str = '')
{
    $str = trim($str);
    if(empty($str)) return '';
    $result = '';
    for($i = 0; $i < strlen($str); $i++) {
        if(is_numeric($str[$i])) {
            $result .= $str[$i];
        }
    }
    return $result;
}

/**
 * @desc arraySort php二维数组排序 按照指定的key 对数组进行排序
 * @param array $arr 将要排序的数组
 * @param string $keys 指定排序的key
 * @param string $type 排序类型 asc | desc
 * @return array
 */
function arraySort($arr, $keys, $type = 'asc') {
    $keysValue = $newArray = array();
    foreach ($arr as $k => $v){
        $keysValue[$k] = $v[$keys];
    }
    $type == 'asc' ? asort($keysValue) : arsort($keysValue);
    reset($keysValue);
    foreach ($keysValue as $k => $v) {
        $newArray[$k] = $arr[$k];
    }
    return $newArray;
}

/**
 * 按符号截取字符串的指定部分
 * @param string $str 需要截取的字符串
 * @param string $sign 需要截取的符号
 * @param int $number 如是正数以0为起点从左向右截  负数则从右向左截
 * @return string 返回截取的内容
 */
function cutStr($str,$sign,$number){
    $array=explode($sign, $str);
    $length=count($array);
    if($number<0){
        $new_array=array_reverse($array);
        $abs_number=abs($number);
        if($abs_number>$length){
            return 'error';
        }else{
            return $new_array[$abs_number-1];
        }
    }else{
        if($number>=$length){
            return 'error';
        }else{
            return $array[$number];
        }
    }
}

function getSign($params, $key)
{
    ksort($params, SORT_STRING);
    $unSignParaString = formatQueryParaMap($params, false);
    \Illuminate\Support\Facades\Log::info('sign_c_params' . json_encode($unSignParaString));
    $signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
    return $signStr;
}

function formatQueryParaMap($paraMap, $urlEncode = false)
{
    $buff = "";
    ksort($paraMap);
    foreach ($paraMap as $k => $v) {
        if (null != $v && "null" != $v) {
            if ($urlEncode) {
                $v = urlencode($v);
            }
            $buff .= $k . "=" . $v . "&";
        }
    }
    $reqPar = '';
    if (strlen($buff) > 0) {
        $reqPar = substr($buff, 0, strlen($buff) - 1);
    }
    return $reqPar;
}

function createNonceStr($length = 16)
{
    $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
    $str = '';
    for ($i = 0; $i < $length; $i++) {
        $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
    }
    return $str;
}